/**
 *    @file       crsa.h
 *
 *    @brief      
 *    @details
 *
 *    @version    1.0
 *    @date       01/24/2014 02:36:51 PM
 *
 *    @author     Theophilus (), wangtf418@gmail.com
 */
#ifndef _BF_CRSA_H_
#define _BF_CRSA_H_
#include <openssl/rsa.h> 
#include <openssl/objects.h>
#include <string>
#include "comdef.h"

enum bf_rsa_keylen_t
{
	BF_RSA_KEYLEN_512 = 64,
	BF_RSA_KEYLEN_1024 = 128,
	BF_RSA_KEYLEN_2048 = 256
};

enum bf_rsa_exponent_t
{
	BF_RSA_EXPONENT_3 = 0x3L,
	BF_RSA_EXPONENT_17 = 0x11L,
	BF_RSA_EXPONENT_65537 = 0x10001L
};

class crsa
{
public:
	crsa();
	~crsa();

public:
	/// Key length with keylen < 1024 should be considered insecure; exp must be an odd num.
	static bf_int_t gen_key(bf_int_t keylen, bf_ulong_t exp, std::string &public_key_n, std::string &public_key_e, std::string &private_key);

	static bf_int_t public_encrypt(const std::string &public_key_n, const std::string &public_key_e,
								const std::string &text, std::string &text_out, bf_int_t padding = RSA_PKCS1_PADDING);
	static bf_int_t private_decrypt(const std::string &public_key_n, const std::string &public_key_e, const std::string &private_key,
								const std::string &text, std::string &text_out, bf_int_t padding = RSA_PKCS1_PADDING);

	static bf_int_t private_encrypt(const std::string &public_key_n, const std::string &public_key_e, const std::string &private_key,
								const std::string &text, std::string &text_out, bf_int_t padding = RSA_PKCS1_PADDING); 
	static bf_int_t public_decrypt(const std::string &public_key_n, const std::string &public_key_e,
								const std::string &text, std::string &text_out, bf_int_t padding = RSA_PKCS1_PADDING);

	static bf_int_t sign(const std::string &public_key_n, const std::string &public_key_e, const std::string &private_key, 
						const std::string &text, std::string &sign_out, bf_int_t type = NID_md5);
	static bf_int_t verify(const std::string &public_key_n, const std::string &public_key_e,
						const std::string &text, const std::string &sign, bf_int_t type = NID_md5);

	static bf_int_t md5_sign(const std::string &public_key_n, const std::string &public_key_e, const std::string &private_key,
						const std::string &text, std::string &sign_out); 
	static bf_int_t md5_verify(const std::string &public_key_n, const std::string &public_key_e,
						const std::string &text, const std::string &sign);

};

#endif

